<?php

// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

namespace think\session\driver;

/**
 * 数据库方式Session驱动
 *    CREATE TABLE think_session (
 *      session_id varchar(255) NOT NULL,
 *      session_expire int(11) NOT NULL,
 *      session_data blob,
 *      UNIQUE KEY `session_id` (`session_id`)
 *    );
 */
use SessionHandler;
use think\Exception;

error_reporting(0);

class Db extends SessionHandler {

        protected $config = [
            'host' => '127.0.0.1', // memcache主机
            'port' => 3306, // memcache端口
            'expire' => 4170000, // session有效期
            'timeout' => 0, // 连接超时时间（单位：毫秒）
            'persistent' => true, // 长连接
            'session_name' => '', // memcache key前缀
        ];

        public function __construct($config = []) {
                $this->config = array_merge($this->config, $config);
        }

        /**
         * Session有效时间
         */
        protected $lifeTime = '';

        /**
         * session保存的数据库名
         */
        protected $sessionTable = '';

        /**
         * 数据库句柄
         */
        protected $hander = array();

        /**
         * 打开Session 
         * @access public 
         * @param string $savePath 
         * @param mixed $sessName  
         */
        public function open($savePath, $sessName) {

                $this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : ini_get('session.gc_maxlifetime');
                $this->sessionTable = C('SESSION_TABLE') ? C('SESSION_TABLE') : C("DB_PREFIX") . "session";
                //分布式数据库
                $host = explode(',', C('database.hostname'));
                $port = explode(',', C('database.hostport'));
                $name = explode(',', C('database.database'));
                $user = explode(',', C('database.username'));
                $pwd = explode(',', C('database.password'));
                if (1 == C('DB_DEPLOY_TYPE')) {
                        //读写分离
                        if (C('DB_RW_SEPARATE')) {
                                $w = floor(mt_rand(0, C('DB_MASTER_NUM') - 1));
                                if (is_numeric(C('DB_SLAVE_NO'))) {//指定服务器读
                                        $r = C('DB_SLAVE_NO');
                                } else {
                                        $r = floor(mt_rand(C('DB_MASTER_NUM'), count($host) - 1));
                                }
                                //主数据库链接
                                $hander = mysqli_connect(
                                        'localhost', isset($user[$r]) ? $user[$r] : $user[0], isset($pwd[$r]) ? $pwd[$r] : $pwd[0], isset($name[$r]) ? $name[$r] : $name[0]
                                );
                                if (!$hander)
                                        return false;
                                $this->hander[0] = $hander;
                                //从数据库链接
                                $hander = mysqli_connect(
                                        'localhost', isset($user[$r]) ? $user[$r] : $user[0], isset($pwd[$r]) ? $pwd[$r] : $pwd[0], isset($name[$r]) ? $name[$r] : $name[0]
                                );
                                if (!$hander)
                                        return false;
                                $this->hander[1] = $hander;
                                return true;
                        }
                }
                //从数据库链接
                $r = floor(mt_rand(0, count($host) - 1));
                /* $hander = mysql_connect(
                  $host[$r] . (isset($port[$r]) ? ':' . $port[$r] : ':' . $port[0]), isset($user[$r]) ? $user[$r] : $user[0], isset($pwd[$r]) ? $pwd[$r] : $pwd[0]
                  );
                  $dbSel = mysql_select_db(
                  isset($name[$r]) ? $name[$r] : $name[0]
                  , $hander); */
                $hander = mysqli_connect(
                        'localhost', isset($user[$r]) ? $user[$r] : $user[0], isset($pwd[$r]) ? $pwd[$r] : $pwd[0], isset($name[$r]) ? $name[$r] : $name[0]
                );
                if (!$hander)
                        return false;
                $this->hander = $hander;
                return true;
        }

        /**
         * 关闭Session 
         * @access public 
         */
        public function close() {
                if (is_array($this->hander)) {
                        $this->gc($this->lifeTime);
                        return (mysqli_close($this->hander[0]) && mysqli_close($this->hander[1]));
                }
                $this->gc($this->lifeTime);
                return mysqli_close($this->hander);
        }

        /**
         * 读取Session 
         * @access public 
         * @param string $sessID 
         */
        public function read($sessID) {
                $hander = is_array($this->hander) ? $this->hander[1] : $this->hander;
                $res = mysqli_query($hander, "SELECT session_data AS data FROM " . $this->sessionTable . " WHERE session_id = '$sessID'   AND session_expire >" . time());
                if ($res) {
                        $row = mysqli_fetch_assoc($res);
                        return $row['data'];
                }
                return "";
        }

        /**
         * 写入Session 
         * @access public 
         * @param string $sessID 
         * @param String $sessData  
         */
        public function write($sessID, $sessData) {
                $hander = is_array($this->hander) ? $this->hander[0] : $this->hander;
                $expire = time() + $this->lifeTime;
                mysqli_query($hander, "REPLACE INTO  " . $this->sessionTable . " (  session_id, session_expire, session_data)  VALUES( '$sessID', '$expire',  '$sessData')");
                if (mysqli_affected_rows($hander))
                        return true;
                return false;
        }

        /**
         * 删除Session 
         * @access public 
         * @param string $sessID 
         */
        public function destroy($sessID) {
                $hander = is_array($this->hander) ? $this->hander[0] : $this->hander;
                mysqli_query($hander, "DELETE FROM " . $this->sessionTable . " WHERE session_id = '$sessID'");
                if (mysqli_affected_rows($hander))
                        return true;
                return false;
        }

        /**
         * Session 垃圾回收
         * @access public 
         * @param string $sessMaxLifeTime 
         */
        public function gc($sessMaxLifeTime) {
                $hander = is_array($this->hander) ? $this->hander[0] : $this->hander;
                mysqli_query($hander, "DELETE FROM " . $this->sessionTable . " WHERE session_expire < " . time());
                return mysqli_affected_rows($hander);
        }

}
